﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Visuals;
using SportTracksSwimSetPlugin.Common;


namespace SportTracksSwimSetPlugin
{
    public partial class SwimSetSettingsControl : UserControl
    {
        public SwimSetSettingsControl()
        {
            InitializeComponent();
            RefreshPage();

        }

        // Summary:
        //     Resets the settings page for the SwimSetPlugin Settings
        //
        // Parameters:
        //     None
        //
        // Returns:
        //     None
        private void RefreshPage()
        {
            CategoryList.Nodes.Clear();
            Plugin swimSetPlugin = new Plugin();
            ILogbookActivityCategoryList catList = 
                swimSetPlugin.Application.Logbook.ActivityCategories;
            
            // add the toplevel categories here
            // and let all the subcategories get added recursively
            // this is due to the toplevel list is a ILogbookActivityCategoryList
            // and it's subcategories are IActivityCategoryList since they inherit 
            // the properties from the parent
            foreach (IActivityCategory category in catList)
            {

                Log.WriteToLogfile("Adding toplevel category: " + category.Name, Log.LogLevel.DEBUG);
                Log.WriteToLogfile("\tRefId: " + category.ReferenceId, Log.LogLevel.DEBUG);
                TreeNode newNode = CategoryList.Nodes.Add(category.Name);
                if (newNode == null)
                {
                    Log.WriteToLogfile("ERROR: failed to add category: " + category.ToString(), Log.LogLevel.WARN);
                }
                newNode.Tag = category;
                if (SwimSetSettings.CategoryList.Contains(category.ReferenceId))
                {
                    newNode.Checked = true;
                }

                if (category.SubCategories != null)
                {
                    addNewCategoryNode(newNode, category.SubCategories);
                }
            }

            hundredPace.Text =
                TimeSpan.FromSeconds(SwimSetSettings.PerHundredPaceSeconds).Minutes.ToString()
                + ":" + TimeSpan.FromSeconds(SwimSetSettings.PerHundredPaceSeconds).Seconds.ToString();
            updateOnImportCB.Checked = SwimSetSettings.UpdateAtImport;

            Log.WriteToLogfile("Done with treeList", Log.LogLevel.DEBUG);
        }

        // Summary:
        //     recursively adds all categorie from a toplevel node
        //     will enable the node if settings are set for the category
        //
        // Parameters:
        //     parentNode - for external calls, this is a toplevel category
        //                  for recursive calls, it's any parent node
        //     subCategories - list of child categories for this new category
        //
        // Returns:
        //     None
        private void addNewCategoryNode(TreeNode parentNode,IActivityCategoryList subCategories)
        {
            Log.WriteToLogfile("Going to check categories with RefIds:", Log.LogLevel.DEBUG);
            foreach (string str in SwimSetSettings.CategoryList)
            {
                Log.WriteToLogfile("\t" + str, Log.LogLevel.DEBUG);
            }
            foreach (IActivityCategory subCategory in subCategories)
            {
                Log.WriteToLogfile("Adding sub category: " + subCategory.Name, Log.LogLevel.DEBUG);

                TreeNode childNode = parentNode.Nodes.Add(subCategory.Name);
                childNode.Tag = subCategory;

                if (SwimSetSettings.CategoryList.Contains(subCategory.ReferenceId))
                {
                    Log.WriteToLogfile("Enabling category: " + childNode.Name, Log.LogLevel.DEBUG);
                    childNode.Checked = true;
                    childNode.EnsureVisible();
                }

                if (subCategory.SubCategories != null)
                {
                    addNewCategoryNode(childNode, subCategory.SubCategories);
                }
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        internal void ThemeChanged(ZoneFiveSoftware.Common.Visuals.ITheme visualTheme)
        {
        }

        internal void UICultureChanged(System.Globalization.CultureInfo culture)
        {
        }

        // Summary:
        //     Recursively sets the checkbox for all children nodes
        //     This is called when a parent nodes is checked, we want to
        //     go ahead and check all of the child nodes, and their child nodes,
        //     and their child nodes ...
        //
        // Parameters:
        //     subNodes - child nodes to recursively check
        //
        // Returns:
        //     None
        private void checkSubNodes(TreeNodeCollection subNodes)
        {
            foreach (TreeNode subNode in subNodes)
            {
                subNode.Checked = true;
                IActivityCategory subCat = (IActivityCategory) subNode.Tag;
                if (!SwimSetSettings.CategoryList.Contains(subCat.ReferenceId))
                    SwimSetSettings.CategoryList.Add(subCat.ReferenceId);

            }
        }

        // Summary:
        //     Recursively unsets the checkbox of a parent node
        //     This is done when a child category is unchecked and
        //     all the siblings and parent categories are checked
        //     We will need to uncheck the parent and parent's parent
        //     and their parents ...
        //
        // Parameters:
        //     parentNode - node to start recursively unchecking (from bottom up)
        //
        // Returns:
        //     None
        private void uncheckParentNodes(TreeNode parentNode)
        {
            parentNode.Checked = false;

            IActivityCategory parentCat = (IActivityCategory)parentNode.Tag;
            if (SwimSetSettings.CategoryList.Contains(parentCat.ReferenceId))
                SwimSetSettings.CategoryList.Remove(parentCat.ReferenceId);
            Log.WriteToLogfile("Removing Category: " + parentCat.Name, Log.LogLevel.DEBUG);

            if (parentNode.Parent != null && parentNode.Parent.Checked == true)
            {
                uncheckParentNodes(parentNode.Parent);
            }
        }

        // Summary:
        //     Action called after a category checkbox is checked/unchecked
        //
        // Parameters:
        //     sender - not used
        //     e - contains category object saved off
        //
        // Returns:
        //     None
        private void CategoryList_AfterCheck(object sender, TreeViewEventArgs eventArgs)
        {
            TreeNode node = (TreeNode)eventArgs.Node;
            IActivityCategory cat = (IActivityCategory)node.Tag;

            // if this node was checked and has child nodes, select them all too
            if (node.Checked)
            {
                // add this category to the settings
                if (!SwimSetSettings.CategoryList.Contains(cat.ReferenceId))
                    SwimSetSettings.CategoryList.Add(cat.ReferenceId);

                // check all the subnodes
                checkSubNodes(node.Nodes);

            }
            else
            {
                // remove this category to the settings
                if (SwimSetSettings.CategoryList.Contains(cat.ReferenceId))
                    SwimSetSettings.CategoryList.Remove(cat.ReferenceId);

                // make sure the parent is unchecked
                if (node.Parent != null)
                {
                    uncheckParentNodes(node.Parent);
                }
            }

        }

        private void CategoryList_AfterSelect_1(object sender, TreeViewEventArgs e)
        {

        }

        // Summary:
        //     Action after the per hundred entry box is left
        //     We need to update the plugin settings
        //
        // Parameters:
        //     Not used
        //
        // Returns:
        //     None
        private void hundredPace_Leave(object sender, EventArgs eventArgs)
        {
            Log.WriteToLogfile("\tNew perhundredPace=" + hundredPace.Text, Log.LogLevel.DEBUG);
            SwimSetSettings.PerHundredPaceSeconds =
                TimeSpan.Parse("00:" + hundredPace.Text).TotalSeconds;
        }

        private void updateOnImportCB_CheckedChanged(object sender, EventArgs eventArgs)
        {
            Log.WriteToLogfile("\tupdateOnImportCB.Checked=" + updateOnImportCB.Checked.ToString(), Log.LogLevel.DEBUG);
            SwimSetSettings.UpdateAtImport = updateOnImportCB.Checked;
            //SwimSetSettings.CategoryList = null;
            //SwimSetSettings.CategoryList = new List<string> { };

        }

        private void useTotalDuration_CheckChanged(object sender, EventArgs eventArgs)
        {
            Log.WriteToLogfile("\tuseTotalDuration.Checked=" + useTotalDuration.Checked.ToString(), Log.LogLevel.DEBUG);
            SwimSetSettings.UseTotalDuration = useTotalDuration.Checked;

        }

    }
}
